home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / Sessions / Movieless in QuickTime / Demo Graphics Importers / DemoGraphicsImporters.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-11  |  48.7 KB  |  2,033 lines  |  [TEXT/CWIE]

  1. #include <MacTypes.h>
  2. #include <Resources.h>
  3. #include <Quickdraw.h>
  4. #include <Fonts.h>
  5. #include <Events.h>
  6. #include <Controls.h>
  7. #include <MacWindows.h>
  8. #include <Menus.h>
  9. #include <TextEdit.h>
  10. #include <Dialogs.h>
  11. #include <Devices.h>
  12. #include <Events.h>
  13. #include <Scrap.h>
  14. #include <ToolUtils.h>
  15. #include <LowMem.h>
  16. #include <MacMemory.h>
  17. #include <Segload.h>
  18. #include <AppleEvents.h>
  19. #include <Files.h>
  20. #include <OSUtils.h>
  21. #include <DiskInit.h>
  22. #include <Packages.h>
  23. #include <Traps.h>
  24. #include <FixMath.h>
  25. #include <NumberFormatting.h>
  26. #include <TextUtils.h>
  27. #include <ColorPicker.h>
  28. #include <Processes.h>
  29. #include <Gestalt.h>
  30. #include <Palettes.h>
  31. #include <Sound.h>
  32. #include <fp.h>
  33.  
  34. #include <ImageCompression.h>
  35. #include <QuickTimeComponents.h>
  36.  
  37. #include <string.h>
  38. #include <stdio.h>
  39.  
  40. #include "DemoGraphicsImporters.h"
  41.  
  42. //
  43. //    Typedefs
  44. //
  45. typedef struct {
  46.     WindowRecord            docWindow;
  47.     FSSpec                    docFSSpec;
  48.     GraphicsImportComponent docGrip;
  49.     GraphicsImportComponent docGripBackground;
  50.     MatrixRecord            docMatrix;
  51.     TEHandle                docText;
  52.     short                    docDemo;
  53.     Rect                    docTranslateBounds;        // used with iTranslate
  54.     Fixed                    docAngle;                // used with iRotate
  55.     Point                    docFourPoints[4];        // labelled clockwise, top-left first
  56.     Boolean                    docCodeVisible;
  57.     Boolean                    docMatrixVisible;
  58.     Boolean                    docFourPointsVisible;
  59.     long                    docTransferModeMenuItem;
  60.     long                    docTransferMode;
  61.     RGBColor                docOpColor;
  62. } DocumentRecord, *DocumentPeek;
  63.  
  64. //
  65. //    Macros
  66. //
  67. #define HiWrd(aLong)    (((aLong) >> 16) & 0xFFFF)
  68. #define LoWrd(aLong)    ((aLong) & 0xFFFF)
  69.  
  70. #define TopLeft(aRect)    (* (Point *) &(aRect).top)
  71. #define BotRight(aRect)    (* (Point *) &(aRect).bottom)
  72.  
  73. #define RectWidth(aRect)    ((long)((aRect).right - (aRect).left))
  74. #define RectHeight(aRect)    ((long)((aRect).bottom - (aRect).top))
  75.  
  76. #define IntToFixed(i)    ((Fixed)(i) << 16)
  77.  
  78. //
  79. //    Application Globals
  80. //
  81. Boolean        gInBackground;
  82. Boolean        gExitFlag = false;
  83.  
  84. //
  85. //    Function Prototypes
  86. //
  87.  
  88. void FitRectIntoRect( const Rect *r, const Rect *s, Rect *t );
  89. void PolyToPolyMatrix(const Fixed *source, const Fixed *dest, MatrixRecord *map);
  90.  
  91. void RectToPoly( Rect *r, Fixed poly[9] );
  92. void FourPointsToPoly( Point fourPoints[4], Fixed poly[9] );
  93. void RectToFourPoints( Rect *r, Point fourPoints[4] );
  94.  
  95. void DrawGraphicInBox( DocumentPeek theDocument, Rect *drawRect );
  96. void DrawGraphicRotated( DocumentPeek theDocument, Rect *drawRect );
  97. void DrawGraphicDistorted( DocumentPeek theDocument, Rect *drawRect );
  98. void DrawFourPoints( DocumentPeek theDocument, Point p[4], short drawMode, Boolean blobs );
  99.  
  100. Fixed WorkOutAngle( Point p, Point c );
  101. short DistanceBetweenPoints( Point a, Point b );
  102. void DoTranslateClick( DocumentPeek theDocument, EventRecord *event );
  103. void DoRotateClick( DocumentPeek theDocument, EventRecord *event );
  104. void DoDistortClick( DocumentPeek theDocument, EventRecord *event );
  105.  
  106. void DrawBackground( DocumentPeek theDocument );
  107. OSErr DrawGraphic( DocumentPeek theDocument );
  108. OSErr DrawMatrix( DocumentPeek theDocument );
  109.  
  110. OSErr SetUpDemoText( DocumentPeek theDocument );
  111. void SetCodeVisible( DocumentPeek theDocument, Boolean visible );
  112. void SetMatrixVisible( DocumentPeek theDocument, Boolean visible );
  113. void SetFourPointsVisible( DocumentPeek theDocument, Boolean visible );
  114.  
  115. void RedrawAfterMatrixChange( DocumentPeek theDocument );
  116. OSErr DrawWindow( WindowPtr window );
  117. void GetDocumentRects( DocumentPeek doc, Rect *outTextRect, Rect *outDrawRect, Rect *outMatrixRect, Rect *outControlsRect );
  118. void ResetDemoMatrix( DocumentPeek theDocument );
  119. void DoMatrixMenu( WindowPtr window, short item );
  120. void DoCompositionMenu( WindowPtr window, short item );
  121. void DoTransferModeMenu( WindowPtr window, short item );
  122. OSErr MakeDocumentControls( DocumentPeek doc, Rect *controlsRect );
  123.  
  124.  
  125. OSErr OpenFSSpec( FSSpec *inFSSpec );
  126. void DoOpen( void );
  127. void DoCloseWindow(WindowPtr window);
  128. void AdjustMenus(void);
  129. void DoMenuCommand(long menuResult);
  130. unsigned long GetSleep(void);
  131. void DoKeyDown(EventRecord *event);
  132. void DoContentClick(WindowPtr window,EventRecord *event);
  133. void DoActivate(WindowPtr window, Boolean becomingActive);
  134. void DoUpdate(WindowPtr    window);
  135. void DoZoomWindow(WindowPtr window,short part);
  136. void DoGrowWindow(WindowPtr    window,EventRecord *event);
  137. void DoIdle();
  138. Boolean ShiftKeyIsDown();
  139. void GetGlobalMouse(Point *mouse);
  140. void AdjustCursor(Point    mouse,RgnHandle    region);
  141. void DoEvent(EventRecord *event);
  142. void DoAppleEvent(EventRecord theEvent);
  143. pascal OSErr DoAEOpenApp(const AppleEvent * message,const AppleEvent * reply,long refcon );
  144. pascal OSErr DoAEOpenDocument(const AppleEvent * message, const AppleEvent * reply, long refcon );
  145. pascal OSErr DoAEQuit(const AppleEvent * message,const AppleEvent * reply,long refcon );        
  146. pascal OSErr DoAEPrintDocuments(const AppleEvent * message, AppleEvent * reply, long refcon );
  147. void InitAppleEvents(void);
  148. void EventLoop(void);
  149. void Terminate( void );
  150. OSErr Initialize( void );
  151. void main(void);
  152.  
  153.  
  154. //
  155. //    FitRectIntoRect
  156. //
  157. void FitRectIntoRect( const Rect *r, const Rect *s, Rect *t )
  158. {
  159.     long r_width = RectWidth(*r);
  160.     long r_height = RectHeight(*r);
  161.     long s_width = RectWidth(*s);
  162.     long s_height = RectHeight(*s);
  163.     if( r_width < s_width && r_height < s_height ) {
  164.         short s_hmid = ( s->left + s->right ) / 2;
  165.         short s_vmid = ( s->top + s->bottom ) / 2;
  166.         short t_half_width = r_width / 2;
  167.         short t_half_height = r_height / 2;
  168.         
  169.         t->top = s_vmid - t_half_height;
  170.         t->bottom = s_vmid + t_half_height;
  171.         t->left = s_hmid - t_half_width;
  172.         t->right = s_hmid + t_half_width;
  173.     } 
  174.     else if( r_width * s_height > r_height * s_width ) {
  175.         short s_vmid = ( s->top + s->bottom ) / 2;
  176.         short t_half_height = FixMul( r_height, FixDiv( s_width, r_width ) ) / 2;
  177.         
  178.         t->top = s_vmid - t_half_height;
  179.         t->bottom = s_vmid + t_half_height;
  180.         t->left = s->left;
  181.         t->right = s->right;
  182.     } else {
  183.         short s_hmid = ( s->left + s->right ) / 2;
  184.         short t_half_width = FixMul( r_width, FixDiv( s_height, r_height ) ) / 2;
  185.         
  186.         t->left = s_hmid - t_half_width;
  187.         t->right = s_hmid + t_half_width;
  188.         t->top = s->top;
  189.         t->bottom = s->bottom;
  190.     }
  191. }
  192.  
  193. //
  194. //    RectToPoly
  195. //
  196. void RectToPoly( Rect *r, Fixed poly[9] )
  197. {
  198.     poly[0] = 4;
  199.     poly[1] = IntToFixed( r->left );
  200.     poly[2] = IntToFixed( r->top );
  201.     poly[3] = IntToFixed( r->right );
  202.     poly[4] = IntToFixed( r->top );
  203.     poly[5] = IntToFixed( r->right );
  204.     poly[6] = IntToFixed( r->bottom );
  205.     poly[7] = IntToFixed( r->left );
  206.     poly[8] = IntToFixed( r->bottom );
  207. }
  208.  
  209. //
  210. //    FourPointsToPoly
  211. //
  212. void FourPointsToPoly( Point fourPoints[4], Fixed poly[9] )
  213. {
  214.     poly[0] = 4;
  215.     poly[1] = IntToFixed( fourPoints[0].h );
  216.     poly[2] = IntToFixed( fourPoints[0].v );
  217.     poly[3] = IntToFixed( fourPoints[1].h );
  218.     poly[4] = IntToFixed( fourPoints[1].v );
  219.     poly[5] = IntToFixed( fourPoints[2].h );
  220.     poly[6] = IntToFixed( fourPoints[2].v );
  221.     poly[7] = IntToFixed( fourPoints[3].h );
  222.     poly[8] = IntToFixed( fourPoints[3].v );
  223. }
  224.  
  225. //
  226. //    RectToFourPoints
  227. //
  228. void RectToFourPoints( Rect *r, Point fourPoints[4] )
  229. {
  230.     fourPoints[0].h = r->left;
  231.     fourPoints[0].v = r->top;
  232.     fourPoints[1].h = r->right;
  233.     fourPoints[1].v = r->top;
  234.     fourPoints[2].h = r->right;
  235.     fourPoints[2].v = r->bottom;
  236.     fourPoints[3].h = r->left;
  237.     fourPoints[3].v = r->bottom;
  238. }
  239.  
  240.  
  241.  
  242. //
  243. //    DrawGraphicInBox
  244. //
  245. void DrawGraphicInBox( DocumentPeek theDocument, Rect *drawRect )
  246. {
  247.     GraphicsImportComponent gi = theDocument->docGrip;
  248.     Rect naturalBounds, bounds;
  249.     MatrixRecord matrix;
  250.     Point naturalBoundsAsPoints[4];
  251.     
  252.     GraphicsImportGetNaturalBounds( gi, &naturalBounds );
  253.     bounds = theDocument->docTranslateBounds;
  254.  
  255.     GraphicsImportSetBoundsRect( gi, &bounds );
  256.     GraphicsImportDraw( gi );
  257.  
  258.     GraphicsImportGetMatrix( gi, &matrix );
  259.     theDocument->docMatrix = matrix;
  260.     
  261.     if( theDocument->docFourPointsVisible ) {
  262.         RectToFourPoints( &naturalBounds, naturalBoundsAsPoints );
  263.         TransformPoints( &matrix, naturalBoundsAsPoints, 4 );
  264.         DrawFourPoints( theDocument, naturalBoundsAsPoints, kDrawSolid, kHideBlobs );
  265.     }
  266. }
  267.  
  268. //
  269. //    DrawGraphicRotated
  270. //
  271. void DrawGraphicRotated( DocumentPeek theDocument, Rect *drawRect )
  272. {
  273.     GraphicsImportComponent gi = theDocument->docGrip;
  274.     Rect naturalBounds, bounds;
  275.     MatrixRecord matrix;
  276.     Fixed angle, x, y;
  277.     Point naturalBoundsAsPoints[4];
  278.     
  279.     GraphicsImportGetNaturalBounds( gi, &naturalBounds );
  280.     FitRectIntoRect( &naturalBounds, drawRect, &bounds );
  281.     
  282.     angle = theDocument->docAngle;
  283.     x = IntToFixed((bounds.right + bounds.left) / 2);
  284.     y = IntToFixed((bounds.bottom + bounds.top) / 2);
  285.     
  286.     RectMatrix( &matrix, &naturalBounds, &bounds );
  287.     RotateMatrix( &matrix, angle, x, y );
  288.     GraphicsImportSetMatrix( gi, &matrix );
  289.     GraphicsImportDraw( gi );
  290.     
  291.     theDocument->docMatrix = matrix;
  292.     
  293.     if( theDocument->docFourPointsVisible ) {
  294.         RectToFourPoints( &naturalBounds, naturalBoundsAsPoints );
  295.         TransformPoints( &matrix, naturalBoundsAsPoints, 4 );
  296.         DrawFourPoints( theDocument, naturalBoundsAsPoints, kDrawSolid, kHideBlobs );
  297.     }
  298. }
  299.  
  300. //
  301. //    DrawGraphicDistorted
  302. //
  303. void DrawGraphicDistorted( DocumentPeek theDocument, Rect *drawRect )
  304. {
  305.     GraphicsImportComponent gi = theDocument->docGrip;
  306.     Rect naturalBounds;
  307.     MatrixRecord matrix;
  308.     Fixed fromPoly[9];
  309.     Fixed toPoly[9];
  310.     
  311.     GraphicsImportGetNaturalBounds( gi, &naturalBounds );
  312.     
  313.     RectToPoly( &naturalBounds, fromPoly );
  314.     FourPointsToPoly( theDocument->docFourPoints, toPoly );
  315.     
  316.     PolyToPolyMatrix( fromPoly, toPoly, &matrix );
  317.     GraphicsImportSetMatrix( gi, &matrix );
  318.     GraphicsImportDraw( gi );
  319.  
  320.     theDocument->docMatrix = matrix;
  321.     
  322.     if( theDocument->docFourPointsVisible )
  323.         DrawFourPoints( theDocument, theDocument->docFourPoints, kDrawSolid, kShowBlobs );
  324. }
  325.  
  326. //
  327. //    DrawFourPoints
  328. //
  329. void DrawFourPoints( DocumentPeek theDocument, Point p[4], short drawMode, Boolean blobs )
  330. {
  331. #pragma unused( theDocument )
  332.     const short thick = 2;
  333.     const short blob = kBlobRadius;
  334.     const RGBColor white = { 0xffff, 0xffff, 0xffff };
  335.     const RGBColor black = { 0x0000, 0x0000, 0x0000 };
  336.     const RGBColor fire  = { 0xffff, 0x6666, 0x0000 };
  337.     const RGBColor dirt  = { 0x6666, 0x3333, 0x2222 };
  338.     short i;
  339.     Boolean erase = (drawMode == kEraseSolid || drawMode == kEraseRubber);
  340.     Boolean rubber_xor;
  341.  
  342.     rubber_xor = 
  343.         (drawMode == kDrawRubber || drawMode == kEraseRubber);
  344.     
  345.     PenSize( thick*2, thick*2 );
  346.     if( rubber_xor ) {
  347.         PenMode( patXor );
  348.         RGBForeColor( &dirt );
  349.     } else {
  350.         RGBForeColor( erase ? &white : &dirt );
  351.     }
  352.  
  353.     MoveTo( p[3].h - thick, p[3].v - thick );
  354.     for( i = 0; i < 4; i++ ) {
  355.         LineTo( p[i].h - thick, p[i].v - thick );
  356.     }
  357.     
  358.     if( blobs ) {
  359.         if( rubber_xor ) {
  360.             RGBForeColor( &dirt );
  361.         } else {
  362.             RGBForeColor( erase ? &white : &fire );
  363.         }
  364.  
  365.         for( i = 0; i < 4; i++ ) {
  366.             Rect r;
  367.             MacSetRect( &r, p[i].h - blob, p[i].v - blob, p[i].h + blob, p[i].v + blob );
  368.             PaintOval( &r );
  369.         }
  370.     }
  371.     
  372.     PenNormal();
  373.     RGBForeColor( &black );
  374. }
  375.  
  376. //
  377. //    DoTranslateClick
  378. //
  379. void DoTranslateClick( DocumentPeek theDocument, EventRecord *event )
  380. {
  381.     GraphicsImportComponent gi = theDocument->docGrip;
  382.     Rect naturalBounds, bounds, startBounds;
  383.     Point startWhere = event->where;
  384.     Point oldWhere = {-9999,-9999}, where;
  385.     Boolean wasDrawn = false;
  386.     Point fourPoints[4];
  387.  
  388.     GlobalToLocal( &startWhere );
  389.  
  390.     GraphicsImportGetNaturalBounds( gi, &naturalBounds );
  391.     bounds = theDocument->docTranslateBounds;
  392.     startBounds = bounds;
  393.     
  394.     RectToFourPoints( &bounds, fourPoints );
  395.     if( theDocument->docFourPointsVisible )
  396.         DrawFourPoints( theDocument, fourPoints, kEraseSolid, kHideBlobs );
  397.  
  398.     do {
  399.         GetMouse( &where );
  400.         
  401.         if( where.h != oldWhere.h || where.v != oldWhere.v )
  402.         {
  403.             if( wasDrawn )
  404.                 DrawFourPoints( theDocument, fourPoints, kEraseRubber, kHideBlobs );
  405.  
  406.             bounds = startBounds;
  407.             OffsetRect( &bounds, where.h - startWhere.h, where.v - startWhere.v );
  408.             
  409.             RectToFourPoints( &bounds, fourPoints );
  410.             
  411.             DrawFourPoints( theDocument, fourPoints, kDrawRubber, kHideBlobs );
  412.             wasDrawn = true;
  413.             
  414.             oldWhere = where;
  415.         }
  416.     } while( StillDown() );    
  417.  
  418.     if( wasDrawn )
  419.         DrawFourPoints( theDocument, fourPoints, kEraseSolid, kHideBlobs );
  420.     
  421.     theDocument->docTranslateBounds = bounds;
  422.     
  423.     RedrawAfterMatrixChange( theDocument );
  424. }
  425.  
  426. //
  427. //    WorkOutAngle
  428. //
  429. Fixed WorkOutAngle( Point p, Point c )
  430. {
  431.     long x = p.h - c.h;
  432.     long y = p.v - c.v;
  433.     return FixMul( FixATan2( y, -x ), FixDiv( IntToFixed(180), X2Fix(3.1415) ) );
  434. }
  435.  
  436. //
  437. //    DoRotateClick
  438. //
  439. void DoRotateClick( DocumentPeek theDocument, EventRecord *event )
  440. {
  441.     GraphicsImportComponent gi = theDocument->docGrip;
  442.     MatrixRecord matrix;
  443.     Rect drawRect;
  444.     Rect naturalBounds, bounds;
  445.     Fixed baseAngle, angle, x, y;
  446.     Point startWhere = event->where;
  447.     Point oldWhere = {-9999,-9999}, where;
  448.     Boolean wasDrawn = false;
  449.     Point naturalBoundsAsPoints[4];
  450.     Point centerOfBounds;
  451.  
  452.     GlobalToLocal( &startWhere );
  453.     GetDocumentRects( theDocument, nil, &drawRect, nil, nil );
  454.  
  455.     angle = theDocument->docAngle;
  456.  
  457.     GraphicsImportGetNaturalBounds( gi, &naturalBounds );
  458.     FitRectIntoRect( &naturalBounds, &drawRect, &bounds );
  459.     centerOfBounds.h = (bounds.right + bounds.left) / 2;
  460.     centerOfBounds.v = (bounds.bottom + bounds.top) / 2;
  461.     x = IntToFixed(centerOfBounds.h);
  462.     y = IntToFixed(centerOfBounds.v);
  463.     
  464.     baseAngle = angle - WorkOutAngle( startWhere, centerOfBounds );
  465.  
  466.     RectToFourPoints( &naturalBounds, naturalBoundsAsPoints );
  467.     RectMatrix( &matrix, &naturalBounds, &bounds );
  468.     RotateMatrix( &matrix, angle, x, y );
  469.     TransformPoints( &matrix, naturalBoundsAsPoints, 4 );
  470.  
  471.     if( theDocument->docFourPointsVisible )
  472.         DrawFourPoints( theDocument, naturalBoundsAsPoints, kEraseSolid, kShowBlobs );
  473.  
  474.     do {
  475.         GetMouse( &where );
  476.         
  477.         if( where.h != oldWhere.h || where.v != oldWhere.v )
  478.         {
  479.             angle = baseAngle + WorkOutAngle( where, centerOfBounds );
  480.             if( ShiftKeyIsDown() ) {
  481.                 const Fixed    moduloAngle = IntToFixed( 45 );
  482.                 angle = ( (angle + moduloAngle/2) / moduloAngle ) * moduloAngle;
  483.             }
  484.             
  485.             oldWhere = where;
  486.             
  487.             if( wasDrawn )
  488.                 DrawFourPoints( theDocument, naturalBoundsAsPoints, kEraseRubber, kShowBlobs );
  489.             
  490.             RectToFourPoints( &naturalBounds, naturalBoundsAsPoints );
  491.             RectMatrix( &matrix, &naturalBounds, &bounds );
  492.             RotateMatrix( &matrix, angle, x, y );
  493.             TransformPoints( &matrix, naturalBoundsAsPoints, 4 );
  494.             
  495.             DrawFourPoints( theDocument, naturalBoundsAsPoints, kDrawRubber, kShowBlobs );
  496.             wasDrawn = true;
  497.         }
  498.     } while( StillDown() );    
  499.  
  500.     if( wasDrawn )
  501.         DrawFourPoints( theDocument, naturalBoundsAsPoints, kEraseSolid, kShowBlobs );
  502.     
  503.     theDocument->docAngle = angle;
  504.     
  505.     RedrawAfterMatrixChange( theDocument );
  506. }
  507.  
  508. //
  509. //    DistanceBetweenPoints
  510. //
  511. short DistanceBetweenPoints( Point a, Point b )
  512. {
  513.     long h = a.h - b.h;
  514.     long v = a.v - b.v;
  515.     return FracSqrt( h*h + v*v ) >> 15;
  516. }
  517.  
  518. //
  519. //    DoDistortClick
  520. //
  521. void DoDistortClick( DocumentPeek theDocument, EventRecord *event )
  522. {
  523.     GraphicsImportComponent gi = theDocument->docGrip;
  524.     Point startWhere = event->where;
  525.     Point oldWhere = {-9999,-9999}, where;
  526.     Boolean wasDrawn = false;
  527.     Point fourPoints[4], originalLoc;
  528.     short whichPoint, whichPointDist, i;
  529.  
  530.     GlobalToLocal( &startWhere );
  531.  
  532.     BlockMove( theDocument->docFourPoints, fourPoints, sizeof(fourPoints) );
  533.     
  534.     whichPoint = -1;
  535.     whichPointDist = 30000;
  536.     for( i = 0; i < 4; i++ ) {
  537.         short dist = DistanceBetweenPoints( fourPoints[i], startWhere );
  538.         if( dist < kBlobRadius && dist < whichPointDist ) {
  539.             whichPoint = i;
  540.             whichPointDist = dist;
  541.         }
  542.     }
  543.     if( -1 == whichPoint )
  544.         return;
  545.     originalLoc = fourPoints[whichPoint];
  546.     
  547.     if( theDocument->docFourPointsVisible )
  548.         DrawFourPoints( theDocument, fourPoints, kEraseSolid, kShowBlobs );
  549.     
  550.     do {
  551.         GetMouse( &where );
  552.         
  553.         if( where.h != oldWhere.h || where.v != oldWhere.v )
  554.         {
  555.             if( wasDrawn )
  556.                 DrawFourPoints( theDocument, fourPoints, kEraseRubber, kShowBlobs );
  557.  
  558.             fourPoints[ whichPoint ].h = originalLoc.h + where.h - startWhere.h;
  559.             fourPoints[ whichPoint ].v = originalLoc.v + where.v - startWhere.v;
  560.             
  561.             oldWhere = where;
  562.             
  563.             DrawFourPoints( theDocument, fourPoints, kDrawRubber, kShowBlobs );
  564.             wasDrawn = true;
  565.         }
  566.     } while( StillDown() );    
  567.  
  568.     BlockMove( fourPoints, theDocument->docFourPoints, sizeof(fourPoints) );
  569.  
  570.     if( wasDrawn )
  571.         DrawFourPoints( theDocument, fourPoints, kEraseSolid, kShowBlobs );
  572.     
  573.     RedrawAfterMatrixChange( theDocument );
  574. }
  575.  
  576. //
  577. //    DrawBackground( DocumentPeek theDocument )
  578. //
  579. void DrawBackground( DocumentPeek theDocument )
  580. {
  581.     if( theDocument->docGripBackground ) {
  582.         GraphicsImportDraw( theDocument->docGripBackground );
  583.     }
  584. }
  585.  
  586. //
  587. //    DrawGraphic
  588. //
  589. OSErr DrawGraphic( DocumentPeek theDocument )
  590. {
  591.     Rect drawRect;
  592.     GetDocumentRects( theDocument, nil, &drawRect, nil, nil );
  593.     
  594.     switch( theDocument->docDemo ) {
  595.         case iTranslate:
  596.             DrawGraphicInBox( theDocument, &drawRect );
  597.             break;
  598.         case iRotate:
  599.             DrawGraphicRotated( theDocument, &drawRect );
  600.             break;
  601.         case iDistort:
  602.             DrawGraphicDistorted( theDocument, &drawRect );
  603.             break;
  604.     }
  605.     
  606.     return noErr;
  607. }
  608.  
  609. //
  610. //    SetUpDemoText
  611. //
  612. OSErr SetUpDemoText( DocumentPeek theDocument )
  613. {
  614.     Rect textRect;
  615.     Ptr textPtr = "-";
  616.     long textLength;
  617.     Boolean hideTransferMode = (theDocument->docTransferMode == srcCopy + ditherCopy);
  618.     
  619.     switch( theDocument->docDemo ) {
  620.         case iTranslate:
  621.             if( hideTransferMode )
  622.                 textPtr = 
  623.                     "GetGraphicsImporterForFile( &fileSpec, &gi );\r"
  624.                     "GraphicsImportSetBoundsRect( gi, &bounds );\r"
  625.                     "GraphicsImportDraw( gi );\r"
  626.                     "CloseComponent( gi );\r";
  627.             else
  628.                 textPtr = 
  629.                     "GetGraphicsImporterForFile( &fileSpec, &gi );\r"
  630.                     "GraphicsImportSetBoundsRect( gi, &bounds );\r"
  631.                     "GraphicsImportSetGraphicsMode( gi, mode, color );\r"
  632.                     "GraphicsImportDraw( gi );\r"
  633.                     "CloseComponent( gi );\r";
  634.             break;
  635.         case iRotate:
  636.             if( hideTransferMode )
  637.                 textPtr = 
  638.                     "GraphicsImportGetNaturalBounds( gi, &natBounds );\r"
  639.                     "RectMatrix( &matrix, &natBounds, &bounds );\r"
  640.                     "RotateMatrix( &matrix, angle, x, y );\r"
  641.                     "GraphicsImportSetMatrix( gi, &matrix );\r"
  642.                     "GraphicsImportDraw( gi );\r";
  643.             else
  644.                 textPtr = 
  645.                     "GraphicsImportGetNaturalBounds( gi, &natBounds );\r"
  646.                     "RectMatrix( &matrix, &natBounds, &bounds );\r"
  647.                     "RotateMatrix( &matrix, angle, x, y );\r"
  648.                     "GraphicsImportSetMatrix( gi, &matrix );\r"
  649.                     "GraphicsImportSetGraphicsMode( gi, mode, color );\r"
  650.                     "GraphicsImportDraw( gi );\r";
  651.             break;
  652.         case iDistort:
  653.             if( hideTransferMode )
  654.                 textPtr = 
  655.                     "PolyToPolyMatrix( fromPoly, toPoly, &matrix );\r"
  656.                     "GraphicsImportSetMatrix( gi, &matrix );\r"
  657.                     "GraphicsImportDraw( gi );\r";
  658.             else
  659.                 textPtr = 
  660.                     "PolyToPolyMatrix( fromPoly, toPoly, &matrix );\r"
  661.                     "GraphicsImportSetMatrix( gi, &matrix );\r"
  662.                     "GraphicsImportSetGraphicsMode( gi, mode, color );\r"
  663.                     "GraphicsImportDraw( gi );\r";
  664.             break;
  665.     }
  666.     textLength = strlen( textPtr );
  667.     
  668.     GetDocumentRects( theDocument, &textRect, nil, nil, nil );
  669.     
  670. /*
  671.     (*theDocument->docText)->txFont = kFontIDCourier;
  672.     (*theDocument->docText)->txSize = 28;
  673.     (*theDocument->docText)->txFace = bold;
  674. */
  675.     
  676.     TEDeactivate( theDocument->docText );
  677.     TESetText( textPtr, textLength, theDocument->docText );
  678.     InvalRect( &textRect );
  679.     
  680.     return noErr;
  681. }
  682.  
  683. //
  684. //    SetCodeVisible
  685. //
  686. void SetCodeVisible( DocumentPeek theDocument, Boolean visible )
  687. {
  688.     WindowPtr window = (WindowPtr) theDocument;
  689.     
  690.     theDocument->docCodeVisible = visible;
  691.     InvalRect( &window->portRect );
  692. }
  693.  
  694. //
  695. //    SetMatrixVisible
  696. //
  697. void SetMatrixVisible( DocumentPeek theDocument, Boolean visible )
  698. {
  699.     WindowPtr window = (WindowPtr) theDocument;
  700.  
  701.     theDocument->docMatrixVisible = visible;
  702.     InvalRect( &window->portRect );
  703. }
  704.  
  705. //
  706. //    SetFourPointsVisible
  707. //
  708. void SetFourPointsVisible( DocumentPeek theDocument, Boolean visible )
  709. {
  710.     WindowPtr window = (WindowPtr) theDocument;
  711.  
  712.     theDocument->docFourPointsVisible = visible;
  713.     InvalRect( &window->portRect );
  714. }
  715.  
  716. //
  717. //    DrawMatrix
  718. //
  719. OSErr DrawMatrix( DocumentPeek theDocument )
  720. {
  721.     WindowPtr window = (WindowPtr) theDocument;
  722.     MatrixRecord matrix = theDocument->docMatrix;
  723.     Rect matrixRect;
  724.     char buf[256];
  725.     StringPtr pstr;
  726.     FontInfo fi;
  727.     short i, j;
  728.     short top, left, right, bottom;
  729.     short topGap  = 10, bottomGap = 10, vertGap  = 20;
  730.     short leftGap = 10, rightGap  = 20, horizGap = 20, fieldWidth;
  731.  
  732.     GetDocumentRects( theDocument, nil, nil, &matrixRect, nil );
  733.     
  734.     TextFont( kFontIDCourier );
  735.     TextSize( 25 );
  736.     TextFace( bold );
  737.     //TextMode( srcCopy );
  738.     GetFontInfo( &fi );
  739.     
  740.     top = matrixRect.top;
  741.     left = matrixRect.left;
  742.     
  743.     topGap += fi.ascent;
  744.     vertGap += fi.ascent + fi.descent;
  745.     bottomGap += fi.descent;
  746.     fieldWidth = 6 * CharWidth( 'x' );
  747.     horizGap += fieldWidth;
  748.     
  749.     right = left + leftGap + 2 * horizGap + fieldWidth + rightGap;
  750.     bottom = top + topGap + 2 * vertGap + bottomGap;
  751.     
  752.     PenSize( 3,3 );
  753.     
  754.     MoveTo( left + leftGap, top );
  755.     LineTo( left, top );
  756.     LineTo( left, bottom );
  757.     LineTo( left + leftGap, bottom );
  758.  
  759.     MoveTo( right - rightGap, top );
  760.     LineTo( right, top );
  761.     LineTo( right, bottom );
  762.     LineTo( right - rightGap, bottom );
  763.     
  764.     PenNormal();
  765.     
  766.     for( i = 0; i < 3; i++ ) {
  767.         for( j = 0; j < 3; j++ ) {
  768.             float_t f;
  769.             MoveTo( left + leftGap + j * horizGap,
  770.                     top + topGap + i * vertGap );
  771.             if( j < 2 ) {
  772.                 f = Fix2X( matrix.matrix[i][j] );
  773.                 sprintf( buf, "%3.1f", f );
  774.             } else {
  775.                 f = Frac2X( matrix.matrix[i][j] );
  776.                 sprintf( buf, "%1.4f", f );
  777.             }
  778.             pstr = c2pstr( buf );
  779.             Move( fieldWidth - StringWidth(pstr), 0 );
  780.             DrawString( pstr );
  781.         }
  782.     }
  783.     
  784.     //InvalRect( &window->portRect );
  785.     
  786.     return noErr;
  787. }
  788.  
  789. //
  790. //    RedrawAfterMatrixChange
  791. //
  792. void RedrawAfterMatrixChange( DocumentPeek theDocument )
  793. {
  794.     WindowPtr window = (WindowPtr) theDocument;
  795.  
  796.     SetPort( window );
  797.     InvalRect( &window->portRect );
  798. }
  799.  
  800. //
  801. //    DrawWindow
  802. //
  803. OSErr 
  804. DrawWindow(
  805.     WindowPtr    window )
  806. {
  807.     DocumentPeek    theDocument = (DocumentPeek) window;
  808.     Rect textRect, drawRect, matrixRect, controlsRect;
  809.     SetPort(window);
  810.     
  811.     GetDocumentRects( theDocument, &textRect, &drawRect, &matrixRect, &controlsRect );
  812.     
  813.     DrawBackground( theDocument );
  814.     
  815.     DrawGraphic( theDocument );
  816.  
  817.     if( theDocument->docMatrixVisible )
  818.         DrawMatrix( theDocument );
  819.     
  820.     DrawControls( window );
  821.     
  822.     //EraseRect( &textRect );
  823.     if( theDocument->docCodeVisible )
  824.         TEUpdate( &textRect, theDocument->docText );
  825.     
  826.     //DrawGrowIcon(window);
  827.     
  828.     return noErr;
  829. } /*DrawWindow*/
  830.  
  831. //
  832. //    ResetDemoMatrix
  833. //
  834. void ResetDemoMatrix( DocumentPeek theDocument )
  835. {
  836.     WindowPtr        window = (WindowPtr) theDocument;
  837.     SetPort( window );
  838.     
  839.     switch( theDocument->docDemo ) {
  840.         case iTranslate:
  841.         {
  842.             Rect drawRect, naturalBounds, bounds;
  843.             GetDocumentRects( theDocument, nil, &drawRect, nil, nil );
  844.             GraphicsImportGetNaturalBounds( theDocument->docGrip, &naturalBounds );
  845.             FitRectIntoRect( &naturalBounds, &drawRect, &bounds );
  846.  
  847.             theDocument->docTranslateBounds = bounds;
  848.         }
  849.             break;
  850.         case iRotate:
  851.             theDocument->docAngle = IntToFixed(90); // 0;
  852.             break;
  853.         case iDistort:
  854.         {
  855.             Rect drawRect, naturalBounds, bounds;
  856.             GetDocumentRects( theDocument, nil, &drawRect, nil, nil );
  857.             GraphicsImportGetNaturalBounds( theDocument->docGrip, &naturalBounds );
  858.             FitRectIntoRect( &naturalBounds, &drawRect, &bounds );
  859.  
  860.             RectToFourPoints( &bounds, theDocument->docFourPoints );
  861.         }
  862.             break;
  863.     }
  864. }
  865. //
  866. //    DoMatrixMenu
  867. //
  868. void DoMatrixMenu( WindowPtr window, short item )
  869. {
  870.     DocumentPeek    theDocument = (DocumentPeek) window;
  871.     SetPort( window );
  872.     
  873.     switch( item ) {
  874.         case iTranslate:
  875.         {
  876.             Rect drawRect, naturalBounds, bounds;
  877.             GetDocumentRects( theDocument, nil, &drawRect, nil, nil );
  878.             GraphicsImportGetNaturalBounds( theDocument->docGrip, &naturalBounds );
  879.             FitRectIntoRect( &naturalBounds, &drawRect, &bounds );
  880.  
  881.             theDocument->docTranslateBounds = bounds;
  882.         }
  883.             break;
  884.         case iRotate:
  885.             theDocument->docAngle = IntToFixed(90); // 0;
  886.             break;
  887.         case iDistort:
  888.         {
  889.             Rect drawRect, naturalBounds, bounds;
  890.             GetDocumentRects( theDocument, nil, &drawRect, nil, nil );
  891.             GraphicsImportGetNaturalBounds( theDocument->docGrip, &naturalBounds );
  892.             FitRectIntoRect( &naturalBounds, &drawRect, &bounds );
  893.  
  894.             RectToFourPoints( &bounds, theDocument->docFourPoints );
  895.         }
  896.             break;
  897.         case iShowCode:
  898.             SetCodeVisible( theDocument, !theDocument->docCodeVisible );
  899.             AdjustMenus();
  900.             break;
  901.         case iShowMatrix:
  902.             SetMatrixVisible( theDocument, !theDocument->docMatrixVisible );
  903.             AdjustMenus();
  904.             break;
  905.         case iShowPoints:
  906.             SetFourPointsVisible( theDocument, !theDocument->docFourPointsVisible );
  907.             AdjustMenus();
  908.             break;
  909.     }
  910.     
  911.     if( item <= iDistort ) {
  912.         SetIdentityMatrix( &theDocument->docMatrix );
  913.         theDocument->docDemo = item;
  914.         ResetDemoMatrix( theDocument );
  915.         SetUpDemoText( theDocument );
  916.         
  917.         RedrawAfterMatrixChange( theDocument );
  918.     }
  919. }
  920.  
  921. //
  922. //    DoCompositionMenu
  923. //
  924. void DoCompositionMenu( WindowPtr window, short item )
  925. {
  926.     DocumentPeek        theDocument = (DocumentPeek) window;
  927.     OSType                theTypeListQTIF[1]    = { kQTFileTypeQuickTimeImage };
  928.     StandardFileReply    theReply;
  929.     FSSpec                fileSpec;
  930.     GraphicsImportComponent gi = 0;
  931.     OSErr                err;
  932.     
  933.     
  934.     StandardGetFilePreview(
  935.         nil,
  936.         1,
  937.         theTypeListQTIF,
  938.         &theReply );
  939.     
  940.     if( ! theReply.sfGood )
  941.         return;
  942.  
  943.     fileSpec = theReply.sfFile;
  944.     err = GetGraphicsImporterForFile( &fileSpec, &gi );
  945.     if( err )
  946.         return;
  947.     if( 0 == gi )
  948.         return;
  949.     
  950.     SetPort( window );
  951.     
  952.     
  953.     switch( item ) {
  954.         case iChangeImage:
  955.             CloseComponent( theDocument->docGrip );
  956.             theDocument->docGrip = gi;
  957.             theDocument->docFSSpec = fileSpec;
  958.             GraphicsImportSetGraphicsMode( 
  959.                     theDocument->docGrip, 
  960.                     theDocument->docTransferMode,
  961.                     &theDocument->docOpColor );
  962.             ResetDemoMatrix( theDocument );
  963.             break;
  964.         case iChangeBackground:
  965.             CloseComponent( theDocument->docGripBackground );
  966.             theDocument->docGripBackground = gi;
  967.             break;
  968.     }
  969.     
  970.     RedrawAfterMatrixChange( theDocument );
  971. }
  972.  
  973. //
  974. //    DoTransferModeMenu
  975. //
  976. void DoTransferModeMenu( WindowPtr window, short item )
  977. {
  978.     DocumentPeek    theDocument = (DocumentPeek) window;
  979.     SetPort( window );
  980.     
  981.     if( iChooseOpColor == item )
  982.     {
  983.         Point        where = { 0,0 };
  984.         RGBColor    thePickedColor;
  985.  
  986.         if( GetColor( where, "\p", &theDocument->docOpColor, &thePickedColor) )
  987.         {
  988.             theDocument->docOpColor = thePickedColor;
  989.             goto done;
  990.         }
  991.         else return;
  992.     }
  993.  
  994.     theDocument->docTransferModeMenuItem = item;
  995.     
  996.     switch( theDocument->docTransferModeMenuItem )
  997.     {
  998.         default:
  999.         case iDitherCopy:
  1000.             theDocument->docTransferMode = srcCopy + ditherCopy;
  1001.             break;
  1002.         case iSrcCopy:
  1003.             theDocument->docTransferMode = srcCopy;
  1004.             break;
  1005.         case iBlend:
  1006.             theDocument->docTransferMode = blend;
  1007.             break;
  1008.         case iTransparent:
  1009.             theDocument->docTransferMode = transparent;
  1010.             break;
  1011.         case iStraightAlpha:
  1012.             theDocument->docTransferMode = graphicsModeStraightAlpha + ditherCopy;
  1013.             break;
  1014.         case iPremulWhiteAlpha:
  1015.             theDocument->docTransferMode = graphicsModePreWhiteAlpha + ditherCopy;
  1016.             break;
  1017.         case iPremulBlackAlpha:
  1018.             theDocument->docTransferMode = graphicsModePreBlackAlpha + ditherCopy;
  1019.             break;
  1020.         case iStraightAlphaBlend:
  1021.             theDocument->docTransferMode = graphicsModeStraightAlphaBlend + ditherCopy;
  1022.             break;
  1023.     }
  1024.     
  1025. done:
  1026.     GraphicsImportSetGraphicsMode( 
  1027.             theDocument->docGrip, 
  1028.             theDocument->docTransferMode,
  1029.             &theDocument->docOpColor );
  1030.     
  1031.     SetUpDemoText( theDocument );
  1032.     RedrawAfterMatrixChange( theDocument );
  1033. }
  1034.  
  1035. //
  1036. //    MakeDocumentControls
  1037. //
  1038. OSErr MakeDocumentControls( DocumentPeek doc, Rect *controlsRect )
  1039. {
  1040.     WindowPtr window = (WindowPtr) doc;
  1041.     
  1042.     return noErr;
  1043. }
  1044.  
  1045. //
  1046. //    GetDocumentRects
  1047. //
  1048. void GetDocumentRects( DocumentPeek doc, Rect *outTextRect, Rect *outDrawRect, Rect *outMatrixRect, Rect *outControlsRect )
  1049. {
  1050.     Rect r = doc->docWindow.port.portRect;
  1051.     short h_mid = (r.left+r.right)/2;
  1052.     short h_right = (r.left+r.right*3)/4;
  1053.     short v_high = (r.top*2+r.bottom)/3;
  1054.     short v_low = (r.top+r.bottom*2)/3;
  1055.  
  1056.     if( outTextRect ) {
  1057.         MacSetRect( outTextRect, r.left, r.top, r.right, v_high );
  1058.         InsetRect( outTextRect, 4, 4 );
  1059.     }
  1060.     if( outDrawRect ) {
  1061.         MacSetRect( outDrawRect, r.left, v_high, h_mid, r.bottom );
  1062.         InsetRect( outDrawRect, 4, 4 );
  1063.     }
  1064.     if( outMatrixRect ) {
  1065.         MacSetRect( outMatrixRect, h_mid, v_low, r.right, r.bottom );
  1066.         InsetRect( outMatrixRect, 4, 4 );
  1067.     }
  1068. /*
  1069.     if( outControlsRect ) {
  1070.         MacSetRect( outControlsRect, hright, vmid, r.right, r.bottom );
  1071.         InsetRect( outControlsRect, 4, 4 );
  1072.     }
  1073. */
  1074. }
  1075.  
  1076. //
  1077. //    OpenFSSpec
  1078. //
  1079. //    Given a file, create a window and open a graphics importer for it.
  1080. //
  1081. OSErr
  1082. OpenFSSpec( FSSpec    *inFSSpec )
  1083. {
  1084.     Ptr                storage;
  1085.     WindowPtr        theWindow = nil;
  1086.     DocumentPeek    theDocument = nil;
  1087.     OSErr            theError = noErr;
  1088.     Rect            textRect, controlRect;
  1089.     RGBColor        rgbcolor_Apple = { 0xefef,0x1e1e,0x1c1c };
  1090.     
  1091.     /* Build a document */
  1092.     storage = NewPtrClear(sizeof(DocumentRecord));
  1093.     if( nil == storage ) 
  1094.         return memFullErr;
  1095.  
  1096.     /* Create a window for the Image */
  1097.     theWindow = GetNewCWindow(kDemoWindowID, storage, (WindowPtr) -1);
  1098.     if( nil == theWindow )
  1099.     {
  1100.         DisposePtr( storage );
  1101.         return memFullErr;
  1102.     }
  1103.     theDocument = (DocumentPeek)theWindow;
  1104.     
  1105.     theDocument->docFSSpec = *inFSSpec;
  1106.     SetIdentityMatrix( &theDocument->docMatrix );
  1107.     theDocument->docDemo = iTranslate;
  1108.     theDocument->docCodeVisible = false;
  1109.     theDocument->docMatrixVisible = false;
  1110.     theDocument->docFourPointsVisible = false;
  1111.     theDocument->docTransferModeMenuItem = iDitherCopy;
  1112.     theDocument->docTransferMode = ditherCopy;
  1113.     theDocument->docOpColor = rgbcolor_Apple;
  1114.  
  1115.     /* Create a graphics import component. */
  1116.     SetPort( theWindow );
  1117.     theError = GetGraphicsImporterForFile( &theDocument->docFSSpec, &theDocument->docGrip );
  1118.  
  1119.     //•• set up something
  1120.     if( noErr == theError ) {
  1121.         GetDocumentRects( theDocument, &textRect, nil, nil, &controlRect );
  1122.         
  1123.         TextFont( kFontIDCourier );
  1124.         TextSize( 25 );
  1125.         TextFace( bold );
  1126.         theDocument->docText = TENew( &textRect, &textRect );
  1127.         
  1128.         if( nil == theDocument->docText )
  1129.             theError = memFullErr;
  1130.     }
  1131.     
  1132.     if( noErr == theError ) {
  1133.         TEDeactivate( theDocument->docText );
  1134.         SetUpDemoText( theDocument );
  1135.         
  1136.         theError = MakeDocumentControls( theDocument, &controlRect );
  1137.     }
  1138.     
  1139.     if( noErr == theError ) {
  1140.         ShowWindow( theWindow );
  1141.         DoMatrixMenu( theWindow, iTranslate );
  1142.     }
  1143.     
  1144.     if( noErr == theError )
  1145.         AdjustMenus();
  1146.  
  1147.     if( theError )
  1148.     {
  1149.         DoCloseWindow( theWindow );
  1150.     }
  1151.  
  1152.     return theError;
  1153. } /* OpenFSSpec */
  1154.  
  1155. //
  1156. //    DoCloseWindow
  1157. //
  1158. void DoCloseWindow(WindowPtr window)
  1159. {
  1160.     DocumentPeek theDocument = (DocumentPeek) window;
  1161.     if( 0 != theDocument->docGrip )
  1162.     {
  1163.         CloseComponent( theDocument->docGrip );
  1164.         theDocument->docGrip = 0;
  1165.     }
  1166.     
  1167.     if( theDocument->docText )
  1168.     {
  1169.         TEDispose( theDocument->docText );
  1170.         theDocument->docText = 0;
  1171.     }
  1172.  
  1173.     MacCloseWindow(window);
  1174.     DisposePtr((Ptr) window);
  1175.     
  1176.     /* SetPort to a valid port for safety */
  1177.     if(FrontWindow())
  1178.         SetPort(FrontWindow());
  1179.     else
  1180.     {
  1181.         GrafPtr    somePort;
  1182.         GetWMgrPort( &somePort );
  1183.         SetPort( somePort );
  1184.     }
  1185.     
  1186.     // Adjust the menus because we may now have no frontmost window.
  1187.     AdjustMenus();
  1188. } /*DoCloseWindow*/
  1189.  
  1190.  
  1191. //
  1192. //    DoOpen
  1193. //
  1194. //    We require QT3.0; just ask for kQTFileTypeQuickTimeImage.
  1195. //
  1196. void
  1197. DoOpen( void )
  1198. {
  1199.     OSType                theTypeListQTIF[1]    = { kQTFileTypeQuickTimeImage };
  1200.     StandardFileReply    theReply;
  1201.     
  1202.     StandardGetFilePreview(
  1203.         nil,
  1204.         1,
  1205.         theTypeListQTIF,
  1206.         &theReply );
  1207.     
  1208.     if( theReply.sfGood )
  1209.         OpenFSSpec( &theReply.sfFile );
  1210. }
  1211. //
  1212. //    DoMenuCommand
  1213. //
  1214. void DoMenuCommand(long menuResult)
  1215. {
  1216.     short        menuID, menuItem;
  1217.     Str255        daName;
  1218.     WindowPtr    window;
  1219.     GrafPtr        savePort;
  1220.  
  1221.     window = FrontWindow();
  1222.     menuID = menuResult >> 16;
  1223.     menuItem = menuResult & 0xffff;
  1224.     
  1225.     switch ( menuID ) {
  1226.         case mApple:
  1227.             switch ( menuItem ) {
  1228.                 case iAboutApp:        /* bring up alert for About */
  1229.                     Alert( kAboutAlertID, nil );
  1230.                     break;
  1231.                 default:            /* all non-About items in this menu are DAs et al */
  1232.                     GetPort(&savePort);
  1233.                     GetMenuItemText(GetMenuHandle(mApple), menuItem, daName);
  1234.                     OpenDeskAcc(daName);
  1235.                     SetPort(savePort);
  1236.                     break;
  1237.             }
  1238.             break;
  1239.  
  1240.         case mFile:
  1241.             switch ( menuItem ) {
  1242.                 case iOpen:
  1243.                     DoOpen();
  1244.                     break;
  1245.                 case iClose:
  1246.                     DoCloseWindow(FrontWindow());
  1247.                     break;
  1248.                 case iQuit:
  1249.                     Terminate();
  1250.                     break;
  1251.             }
  1252.             break;
  1253.  
  1254.         case mEdit:
  1255.             break;
  1256.         
  1257.         case mMatrix:
  1258.             DoMatrixMenu( window, menuItem );
  1259.             break;
  1260.  
  1261.         case mComposition:
  1262.             DoCompositionMenu( window, menuItem );
  1263.             break;
  1264.  
  1265.         case mTransferMode:
  1266.             DoTransferModeMenu( window, menuItem );
  1267.             break;
  1268.  
  1269.     }
  1270.     HiliteMenu(0);                    /* unhighlight what MenuSelect (or MenuKey) hilited */
  1271. } /*DoMenuCommand*/
  1272.  
  1273. //
  1274. //    AdjustMenus
  1275. //
  1276. void AdjustMenus(void)
  1277. {
  1278.     WindowPtr    window;
  1279.     DocumentPeek theDocument;
  1280.     MenuHandle    menu;
  1281.     short i;
  1282.  
  1283.     window = FrontWindow();
  1284.     theDocument = (DocumentPeek) window;
  1285.     
  1286.     menu = GetMenuHandle(mFile);
  1287.     if ( window != nil )
  1288.     {
  1289.         EnableItem(menu, iClose);
  1290.     }
  1291.     else
  1292.     {
  1293.         DisableItem(menu, iClose);
  1294.     }
  1295.     
  1296.     menu = GetMenuHandle(mEdit);
  1297.     DisableItem(menu, iUndo);
  1298.     DisableItem(menu, iCut);
  1299.     DisableItem(menu, iCopy);
  1300.     DisableItem(menu, iPaste);
  1301.     DisableItem(menu, iClear);
  1302.  
  1303.     menu = GetMenuHandle(mMatrix);
  1304.     if ( window != nil )
  1305.     {
  1306.         EnableItem(menu, 0);
  1307.         CheckItem(menu, iTranslate, iTranslate == theDocument->docDemo );
  1308.         CheckItem(menu, iRotate,    iRotate == theDocument->docDemo );
  1309.         CheckItem(menu, iDistort,   iDistort == theDocument->docDemo );
  1310.         CheckItem(menu, iShowCode,   theDocument->docCodeVisible );
  1311.         CheckItem(menu, iShowMatrix, theDocument->docMatrixVisible );
  1312.         CheckItem(menu, iShowPoints, theDocument->docFourPointsVisible );
  1313.     }
  1314.     else
  1315.     {
  1316.         DisableItem(menu, 0);
  1317.     }
  1318.  
  1319.     menu = GetMenuHandle(mComposition);
  1320.     if ( window != nil )
  1321.         EnableItem(menu, 0);
  1322.     else
  1323.         DisableItem(menu, 0);
  1324.  
  1325.     menu = GetMenuHandle(mTransferMode);
  1326.     if ( window != nil )
  1327.     {
  1328.         EnableItem(menu, 0);
  1329.         for( i = iDitherCopy; i <= iStraightAlphaBlend; i++ )
  1330.             CheckItem(menu, i, i == theDocument->docTransferModeMenuItem );
  1331.     }
  1332.     else
  1333.     {
  1334.         DisableItem(menu, 0);
  1335.     }
  1336.  
  1337.     DrawMenuBar();
  1338. } /*AdjustMenus*/
  1339.  
  1340. //
  1341. //    GetSleep
  1342. //
  1343. unsigned long GetSleep(void)
  1344. {
  1345.     long        sleep;
  1346.     sleep = 60;
  1347.     return sleep;
  1348. } /*GetSleep*/
  1349.  
  1350. //
  1351. //    DoKeyDown
  1352. //
  1353. void DoKeyDown(EventRecord *event)
  1354. {
  1355. } /*DoKeyDown*/
  1356.  
  1357. //
  1358. //    DoContentClick
  1359. //
  1360. void DoContentClick(WindowPtr window,EventRecord *event)
  1361. {
  1362.     DocumentPeek theDocument = (DocumentPeek)window;
  1363.     switch( theDocument->docDemo ) {
  1364.         case iTranslate:
  1365.             DoTranslateClick( theDocument, event );
  1366.             break;
  1367.         case iRotate:
  1368.             DoRotateClick( theDocument, event );
  1369.             break;
  1370.         case iDistort:
  1371.             DoDistortClick( theDocument, event );
  1372.             break;
  1373.     }
  1374. } /*DoContentClick*/
  1375.  
  1376.  
  1377. //
  1378. //    DoActivate
  1379. //
  1380. void DoActivate(WindowPtr window, Boolean becomingActive)
  1381. {
  1382. } /*DoActivate*/
  1383.  
  1384. //
  1385. //    DoUpdate
  1386. //
  1387. void DoUpdate(WindowPtr    window)
  1388. {
  1389.     SetPort( window );
  1390.     BeginUpdate(window); /* this sets up the visRgn */
  1391.     if ( ! EmptyRgn(window->visRgn) ) {
  1392.         EraseRect(&window->portRect);
  1393.         DrawWindow(window);
  1394.     }
  1395.     EndUpdate(window);
  1396. } /*DoUpdate*/
  1397.  
  1398. //
  1399. //    DoZoomWindow
  1400. //
  1401. void DoZoomWindow(WindowPtr window,short part)
  1402. {
  1403.     SetPort(window);
  1404.     EraseRect(&window->portRect);
  1405.     ZoomWindow(window, part, window == FrontWindow());
  1406. } /*  DoZoomWindow */
  1407.  
  1408. //
  1409. //    DoGrowWindow
  1410. //
  1411. void DoGrowWindow(WindowPtr    window,EventRecord    *event)
  1412. {
  1413.     long        growResult;
  1414.     Rect        tempRect;
  1415.     DocumentPeek theDocument = (DocumentPeek) window;
  1416.     
  1417.     SetRect( &tempRect, 64, 64, 9999, 9999 );
  1418.     growResult = GrowWindow(window, event->where, &tempRect);
  1419.     /* see if it really changed size */
  1420.     if ( growResult != 0 ) {
  1421.         SetPort( window );
  1422.         SizeWindow(window, LoWrd(growResult), HiWrd(growResult), true);
  1423.     }
  1424. } /* DoGrowWindow */
  1425.  
  1426. //
  1427. //    GetGlobalMouse
  1428. //
  1429. void GetGlobalMouse(Point *mouse)
  1430. {
  1431.     EventRecord    event;
  1432.     
  1433.     OSEventAvail(0, &event);
  1434.     *mouse = event.where;
  1435. } /*GetGlobalMouse*/
  1436.  
  1437. //
  1438. //    ShiftKeyIsDown
  1439. //
  1440. Boolean ShiftKeyIsDown()
  1441. {
  1442.     EventRecord    event;
  1443.     
  1444.     OSEventAvail(0, &event);
  1445.     return 0 != (event.modifiers & shiftKey);
  1446. } /*GetGlobalMouse*/
  1447.  
  1448.  
  1449. //
  1450. //    AdjustCursor
  1451. //
  1452. void AdjustCursor(Point    mouse,RgnHandle    region)
  1453. {
  1454.     if( ! gInBackground ) {
  1455.         SetCursor(&qd.arrow);
  1456.     }
  1457. } /*AdjustCursor*/
  1458.  
  1459. //
  1460. //    DoIdle
  1461. //
  1462. void DoIdle()
  1463. {
  1464.     
  1465. }
  1466.  
  1467. //
  1468. //    DoEvent
  1469. //
  1470. void DoEvent(EventRecord *event)
  1471. {
  1472.     short        part;
  1473.     WindowPtr    window;
  1474.     short        key;
  1475.  
  1476.     switch ( event->what ) {
  1477.         case nullEvent:
  1478.             DoIdle();
  1479.             break;
  1480.         case mouseDown:
  1481.             part = FindWindow(event->where, &window);
  1482.             switch ( part ) {
  1483.                 case inMenuBar:             /* process a mouse menu command (if any) */
  1484.                     AdjustMenus();    /* bring ’em up-to-date */
  1485.                     DoMenuCommand(MenuSelect(event->where));
  1486.                     break;
  1487.                 case inSysWindow:           /* let the system handle the mouseDown */
  1488.                     SystemClick(event, window);
  1489.                     break;
  1490.                 case inContent:
  1491.                     if ( window != FrontWindow() ) {
  1492.                         SelectWindow(window);
  1493.                     } else
  1494.                         DoContentClick(window, event);
  1495.                     break;
  1496.                 case inDrag:                /* pass screenBits.bounds to get all gDevices */
  1497.                     DragWindow(window, event->where, &qd.screenBits.bounds);
  1498.                     break;
  1499.                 case inGoAway:
  1500.                     if ( TrackGoAway(window, event->where) )
  1501.                         DoCloseWindow(window);
  1502.                     break;
  1503.                 case inGrow:
  1504.                     DoGrowWindow(window, event);
  1505.                     break;
  1506.                 case inZoomIn:
  1507.                 case inZoomOut:
  1508.                 if ( TrackBox(window, event->where, part) )
  1509.                         DoZoomWindow(window, part);
  1510.                     break;
  1511.             }
  1512.             break;
  1513.         case keyDown:
  1514.         case autoKey:                       /* check for menukey equivalents */
  1515.             key = event->message & charCodeMask;
  1516.             if ( event->modifiers & cmdKey ) {    /* Command key down */
  1517.                 if ( event->what == keyDown ) {
  1518.                     AdjustMenus();            /* enable/disable/check menu items properly */
  1519.                     DoMenuCommand(MenuKey(key));
  1520.                 }
  1521.             } else
  1522.                 DoKeyDown(event);
  1523.             break;
  1524.         case activateEvt:
  1525.             DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
  1526.             break;
  1527.         case updateEvt:
  1528.             DoUpdate((WindowPtr) event->message);
  1529.             break;
  1530.         case osEvt:
  1531.             switch ((event->message >> 24) & 0x0FF) {        /* high byte of message */
  1532.                 case mouseMovedMessage:
  1533.                     DoIdle();
  1534.                     break;
  1535.                 case suspendResumeMessage:        /* suspend/resume is also an activate/deactivate */
  1536.                     gInBackground = (event->message & resumeFlag) == 0;
  1537.                     DoActivate(FrontWindow(), !gInBackground);
  1538.                     break;
  1539.             }
  1540.             break;
  1541.         /*case kHighLevelEvent: 
  1542.             DoAppleEvent( *event );
  1543.             break;*/
  1544.     }
  1545. } /*DoEvent*/
  1546.  
  1547. //====================================================================================
  1548. //
  1549. //    AppleEvent handling.
  1550. //
  1551.  
  1552. //
  1553. //    DoAppleEvent
  1554. //
  1555. void 
  1556. DoAppleEvent( 
  1557.     EventRecord theEvent )
  1558. {
  1559.     OSErr err;
  1560.  
  1561.   // should check for your own event message types here - if you have any
  1562.     
  1563.     err = AEProcessAppleEvent(&theEvent);
  1564. }
  1565.  
  1566. //
  1567. //    DoAEOpenApp
  1568. //
  1569. pascal OSErr 
  1570. DoAEOpenApp(
  1571.     const AppleEvent * message,
  1572.     const AppleEvent * reply,
  1573.     long refcon )
  1574. {
  1575.     return noErr;
  1576. }
  1577.  
  1578. //
  1579. //    DoAEOpenDocument
  1580. //
  1581. pascal OSErr 
  1582. DoAEOpenDocument(
  1583.     const AppleEvent * message, 
  1584.     const AppleEvent * reply, 
  1585.     long refcon )
  1586. {
  1587.     long        index;
  1588.     long        itemsInList;
  1589.     AEKeyword   keywd;
  1590.     OSErr       err;
  1591.     OSErr       ignoreErr;
  1592.     AEDescList  docList;
  1593.     long        actSize;
  1594.     DescType    typeCode;
  1595.     FSSpec      theFSSpec;
  1596.  
  1597.     /*open the specified documents*/
  1598.  
  1599.     docList.dataHandle = nil;
  1600.  
  1601.     err = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList);
  1602.  
  1603.     if (err==noErr)
  1604.     {
  1605.         err = AECountItems( &docList, &itemsInList) ;
  1606.     }
  1607.     else
  1608.     {
  1609.         itemsInList = 0;
  1610.     }
  1611.     
  1612.     for (index = 1; index <= itemsInList; index++)
  1613.         if (err==noErr)
  1614.         {
  1615.             err = AEGetNthPtr( &docList, index, typeFSS, &keywd, &typeCode,
  1616.                                                  (Ptr)&theFSSpec, sizeof(theFSSpec), &actSize ) ;
  1617.             if (err==noErr)
  1618.             {
  1619.                 OpenFSSpec( &theFSSpec );
  1620.             }
  1621.         }
  1622.  
  1623.     if (docList.dataHandle)
  1624.     {
  1625.         ignoreErr = AEDisposeDesc(&docList);
  1626.     }
  1627.     
  1628.     return err;
  1629. }
  1630.  
  1631. //
  1632. //    DoAEQuit
  1633. //
  1634. pascal OSErr 
  1635. DoAEQuit(
  1636.     const AppleEvent * message,
  1637.     const AppleEvent * reply,
  1638.     long refcon )            
  1639. {
  1640.     Terminate();
  1641.     return noErr;
  1642. }
  1643.  
  1644.  
  1645. //
  1646. //    DoAEPrintDocuments
  1647. //
  1648. pascal OSErr 
  1649. DoAEPrintDocuments(
  1650.     const AppleEvent * message, 
  1651.     AppleEvent * reply, 
  1652.     long refcon )
  1653. {
  1654.     return errAEEventFailed;
  1655. } /* DoPrintDocuments */
  1656.  
  1657.  
  1658. //
  1659. //    InitAppleEvents
  1660. //
  1661. void
  1662. InitAppleEvents(void)
  1663. {
  1664.     const long noRefCon = 0;
  1665.     OSErr aevtErr;
  1666.     
  1667.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc(DoAEOpenApp), noRefCon, false) ;
  1668.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments,   NewAEEventHandlerProc(DoAEOpenDocument), noRefCon, false) ;
  1669.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEPrintDocuments,  NewAEEventHandlerProc(DoAEPrintDocuments), noRefCon, false) ;
  1670.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(DoAEQuit), noRefCon, false) ;
  1671. }
  1672.  
  1673. //====================================================================================
  1674.  
  1675. /* ******************************** PolyToPolyMatrix ******************************** */
  1676.  
  1677. // PolyToPolyMatrix takes two polygons and generates a matrix mapping from one to the other.
  1678. // The two polygons are stored as arrays of longs; the first long is the number of points
  1679. // in the polygon; the points follow as FixedPoints: x, then y.
  1680. // Both polygons should have the same number of points.  
  1681. // Polygons with more than 4 points will be treated as though they had only 4 points.
  1682.  
  1683. static long MultiplyDivide(long source, long multiplier, long divisor)
  1684. {
  1685.     wide temp;
  1686.     CompMul(source, multiplier, &temp);
  1687.     return CompDiv(&temp, divisor, 0);
  1688. }
  1689.  
  1690. static wide *VectorMultiply(register long count, register const long *vector1, register long step1,
  1691.             register const long *vector2, register long step2, register wide *dot)
  1692. {
  1693.     short flags = count >= 0;
  1694.     dot->hi = dot->lo = 0;
  1695.     if (!flags)
  1696.         count = -count;
  1697.     while (count--)
  1698.     {    wide temp;
  1699.         if (flags ^= 2)
  1700.         {
  1701.             CompMul(*vector1, *vector2, &temp);
  1702.             CompAdd(&temp, dot);
  1703.         }
  1704.         else
  1705.         {
  1706.             CompMul(*vector1, *vector2, &temp);
  1707.             CompSub(&temp, dot);
  1708.         }
  1709.         vector1 += step1;
  1710.         vector2 += step2;
  1711.     }
  1712.     return dot;
  1713. }
  1714.  
  1715. static long VectorMultiplyDivide(long count, const long *vector1, long step1, const long *vector2, long step2, long scalar)
  1716. {
  1717.     wide temp;
  1718.     return CompDiv(VectorMultiply(count, vector1, step1, vector2, step2, &temp), scalar, 0);
  1719. }
  1720.  
  1721. // ------------------------------------------------------------------------------------------
  1722. static unsigned long MyWideSquareRoot(const wide *src)
  1723. {
  1724.     {    register unsigned long srchi=src->hi;
  1725.         register unsigned long srclo=src->lo;
  1726.         register unsigned long root=0;
  1727.         register unsigned long left=0;
  1728.         register unsigned long delta=0;
  1729.         unsigned short i, lefthi, deltahi;
  1730.     
  1731.         i = 16;                        /* compute the first 16 bits */
  1732.         while (i--)
  1733.         {    left = left << 2 | srchi >> 30;
  1734.             srchi <<= 2;
  1735.             root <<= 1;
  1736.             delta = (root << 1) + 1;
  1737.             if (left >= delta)
  1738.             {    left -= delta;
  1739.                 root += 1;
  1740.             }
  1741.         }
  1742.     
  1743.         i = 14;                        /* compute the next 14 bits */
  1744.         while(i--)
  1745.         {    left = left << 2 | srclo >> 30;
  1746.             srclo <<= 2;
  1747.             root <<= 1;
  1748.             delta = (root << 1) + 1;
  1749.             if (left >= delta)
  1750.             {    left -= delta;
  1751.                 root += 1;
  1752.             }
  1753.         }
  1754.     
  1755.         i = 2;                        /* compute the last two bits */
  1756.         while (i--)
  1757.         {    lefthi = left >> 30;
  1758.             left = left << 2 | srclo >> 30;
  1759.             srclo <<= 2;
  1760.             root <<= 1;
  1761.             deltahi = root >> 31;
  1762.             delta = (root << 1) + 1;
  1763.             if (lefthi > deltahi || lefthi == deltahi && left >= delta)
  1764.             {    if (left < delta)
  1765.                     lefthi -= deltahi + 1;
  1766.                 else
  1767.                     lefthi -= deltahi;
  1768.                 left -= delta;
  1769.                 root += 1;
  1770.             }
  1771.         }
  1772.     
  1773.         if (lefthi || left > root)            /* round */
  1774.             if (root + 1)                /* don't exceed 32 bits */
  1775.                 root += 1;
  1776.     
  1777.         return root;
  1778.     }
  1779. }
  1780.  
  1781. static unsigned long Magnitude(long deltaX, long deltaY)
  1782. {
  1783.     wide temp1, temp2;
  1784.  
  1785.     if (deltaX == 0)
  1786.         return deltaY < 0 ? -deltaY : deltaY;
  1787.     if (deltaY == 0)
  1788.         return deltaX < 0 ? -deltaX : deltaX;
  1789.     CompMul(deltaX, deltaX, &temp1);
  1790.     CompMul(deltaY, deltaY, &temp2);
  1791.     CompAdd(&temp1, &temp2);
  1792.     return MyWideSquareRoot(&temp2);
  1793. }
  1794.  
  1795. static void PolyToPoint(const Fixed *poly, FixedPoint *pt)
  1796. {
  1797.     register Fixed x = fixed1, y = fixed1;
  1798.     FixedPoint pt1, pt2;
  1799.  
  1800.     if (poly[0] > 1)
  1801.     {   pt1.x = poly[3] - poly[1];
  1802.         pt1.y = poly[4] - poly[2];
  1803.         y = Magnitude(pt1.x, pt1.y);
  1804.         switch (poly[0])
  1805.         {   case 2:
  1806.             break;
  1807.             case 3:
  1808.                 pt2.x = poly[2] - poly[6];
  1809.                 pt2.y = poly[5] - poly[1];
  1810.             goto calcX;
  1811.             default:
  1812.                 pt2.x = poly[2] - poly[8];
  1813.                 pt2.y = poly[7] - poly[1];
  1814.             calcX:
  1815.                 x = VectorMultiplyDivide(2, &pt1.x, 1, &pt2.x, 1, y);
  1816.             break;
  1817.         }
  1818.     }
  1819.     pt->x = x;
  1820.     pt->y = y;
  1821. }
  1822.  
  1823. static void Map1Pt(const FixedPoint *source, Fixed *dest)
  1824. {
  1825.     register Fixed *destPtr = dest;
  1826.     register const FixedPoint *srcPt = source;
  1827.     *destPtr++ = fixed1;
  1828.     *destPtr++ = 0;
  1829.     *destPtr++ = 0;
  1830.     *destPtr++ = 0;
  1831.     *destPtr++ = fixed1;
  1832.     *destPtr++ = 0;
  1833.     *destPtr++ = srcPt[0].x;
  1834.     *destPtr++ = srcPt[0].y;
  1835.     *destPtr = fract1;
  1836. }
  1837.  
  1838. static void Map2Pt(const FixedPoint *source, Fixed *dest, Fixed scale)
  1839. {
  1840.     register Fixed *destPtr = dest;
  1841.     register const FixedPoint *srcPt = source;
  1842.     *destPtr++ = FixDiv(srcPt[1].y - srcPt[0].y, scale);
  1843.     *destPtr++ = FixDiv(srcPt[0].x - srcPt[1].x, scale);
  1844.     *destPtr++ = 0;
  1845.     *destPtr++ = FixDiv(srcPt[1].x - srcPt[0].x, scale);
  1846.     *destPtr++ = FixDiv(srcPt[1].y - srcPt[0].y, scale);
  1847.     *destPtr++ = 0;
  1848.     *destPtr++ = srcPt[0].x;
  1849.     *destPtr++ = srcPt[0].y;
  1850.     *destPtr = fract1;
  1851. }
  1852.  
  1853. static void Map3Pt(const FixedPoint *source, Fixed *dest, Fixed scaleX, Fixed scaleY)
  1854. {
  1855.     register Fixed *destPtr = dest;
  1856.     register const FixedPoint *srcPt = source;
  1857.     *destPtr++ = FixDiv(srcPt[2].x - srcPt[0].x, scaleX);
  1858.     *destPtr++ = FixDiv(srcPt[2].y - srcPt[0].y, scaleX);
  1859.     *destPtr++ = 0;
  1860.     *destPtr++ = FixDiv(srcPt[1].x - srcPt[0].x, scaleY);
  1861.     *destPtr++ = FixDiv(srcPt[1].y - srcPt[0].y, scaleY);
  1862.     *destPtr++ = 0;
  1863.     *destPtr++ = srcPt[0].x;
  1864.     *destPtr++ = srcPt[0].y;
  1865.     *destPtr = fract1;
  1866. }
  1867.  
  1868. static void Map4Pt(const FixedPoint *source, Fixed *dest, Fixed scaleX, Fixed scaleY)
  1869. {
  1870.     register Fixed *destPtr = dest;
  1871.     register const FixedPoint *srcPt = source;
  1872.     Fract a1, a2;
  1873.     Fixed x0, y0, x1, y1, x2, y2;
  1874.  
  1875.     x0 = srcPt[2].x - srcPt[0].x;
  1876.     y0 = srcPt[2].y - srcPt[0].y;
  1877.     x1 = srcPt[2].x - srcPt[1].x;
  1878.     y1 = srcPt[2].y - srcPt[1].y;
  1879.     x2 = srcPt[2].x - srcPt[3].x;
  1880.     y2 = srcPt[2].y - srcPt[3].y;
  1881.  
  1882.     // check if abs(x2) > abs(y2) 
  1883.     if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2)
  1884.         a1 = FracDiv(MultiplyDivide(x0 - x1, y2, x2) - y0 + y1, MultiplyDivide(x1, y2, x2) - y1);
  1885.     else
  1886.         a1 = FracDiv(x0 - x1 - MultiplyDivide(y0 - y1, x2, y2), x1 - MultiplyDivide(y1, x2, y2));
  1887.  
  1888.     // check if abs(x1) > abs(y1) 
  1889.     if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1)
  1890.         a2 = FracDiv(y0 - y2 - MultiplyDivide(x0 - x2, y1, x1), y2 - MultiplyDivide(x2, y1, x1));
  1891.     else
  1892.         a2 = FracDiv(MultiplyDivide(y0 - y2, x1, y1) - x0 + x2, MultiplyDivide(y2, x1, y1) - x2);
  1893.  
  1894.     *destPtr++ = FixDiv(FracMul(a2, srcPt[3].x) + srcPt[3].x - srcPt[0].x, scaleX);
  1895.     *destPtr++ = FixDiv(FracMul(a2, srcPt[3].y) + srcPt[3].y - srcPt[0].y, scaleX);
  1896.     *destPtr++ = FixDiv(a2, scaleX);
  1897.     *destPtr++ = FixDiv(FracMul(a1, srcPt[1].x) + srcPt[1].x - srcPt[0].x, scaleY);
  1898.     *destPtr++ = FixDiv(FracMul(a1, srcPt[1].y) + srcPt[1].y - srcPt[0].y, scaleY);
  1899.     *destPtr++ = FixDiv(a1, scaleY);
  1900.     *destPtr++ = srcPt[0].x;
  1901.     *destPtr++ = srcPt[0].y;
  1902.     *destPtr = fract1;
  1903. }
  1904.  
  1905. void PolyToPolyMatrix(const Fixed *source, const Fixed *dest, MatrixRecord *map)
  1906. {
  1907.     FixedPoint tempPt;
  1908.     MatrixRecord tempMap;
  1909.     long vectors = source[0];
  1910.  
  1911.     PolyToPoint(source, &tempPt);
  1912.     switch (vectors)
  1913.     {   case 0:
  1914.             SetIdentityMatrix(map);
  1915.             break;
  1916.         case 1:
  1917.             Map1Pt((FixedPoint*)&source[1], &tempMap.matrix[0][0]);
  1918.             InverseMatrix(&tempMap, map);
  1919.             Map1Pt((FixedPoint*)&dest[1], &tempMap.matrix[0][0]);
  1920.             goto mapMap;
  1921.         case 2:
  1922.             Map2Pt((FixedPoint*)&source[1], &tempMap.matrix[0][0], tempPt.y);
  1923.             InverseMatrix(&tempMap, map);
  1924.             Map2Pt((FixedPoint*)&dest[1], &tempMap.matrix[0][0], tempPt.y);
  1925.             goto mapMap;
  1926.         case 3:
  1927.             Map3Pt((FixedPoint*)&source[1], &tempMap.matrix[0][0], tempPt.x, tempPt.y);
  1928.             InverseMatrix(&tempMap, map);
  1929.             Map3Pt((FixedPoint*)&dest[1], &tempMap.matrix[0][0], tempPt.x, tempPt.y);
  1930.             goto mapMap;
  1931.         default:
  1932.             Map4Pt((FixedPoint*)&source[1], &tempMap.matrix[0][0], tempPt.x, tempPt.y);
  1933.             InverseMatrix(&tempMap, map);
  1934.             Map4Pt((FixedPoint*)&dest[1], &tempMap.matrix[0][0], tempPt.x, tempPt.y);
  1935.         mapMap:
  1936.             ConcatMatrix(&tempMap, map);
  1937.             break;
  1938.     }
  1939. }
  1940.  
  1941. /* ******************************************************************************* */
  1942.  
  1943. //====================================================================================
  1944.  
  1945. //
  1946. //    EventLoop
  1947. //
  1948. void EventLoop(void)
  1949. {
  1950.     Boolean        gotEvent;
  1951.     EventRecord    event;
  1952.     Point        mouse;
  1953.  
  1954.     do {
  1955.         GetGlobalMouse(&mouse);
  1956.         gotEvent = WaitNextEvent(everyEvent, &event, GetSleep(), nil);
  1957.         if ( gotEvent ) {
  1958.             /* make sure we have the right cursor before handling the event */
  1959.             AdjustCursor(event.where, nil);
  1960.             DoEvent(&event);
  1961.         }
  1962.         else
  1963.         {
  1964.             DoIdle();                /* perform idle tasks when it’s not our event */
  1965.         }
  1966.     } while ( !gExitFlag );
  1967.     
  1968. } /*EventLoop*/
  1969.  
  1970. //
  1971. //    Terminate
  1972. //
  1973. void Terminate(void)
  1974. {
  1975.     gExitFlag = true;
  1976. } /*Terminate*/
  1977.  
  1978.  
  1979. //
  1980. //    Initialize
  1981. //
  1982. OSErr Initialize(void)
  1983. {
  1984.     Handle    menuBar;
  1985.     EventRecord event;
  1986.     short    count;
  1987.     long    theResult = 0;
  1988.     OSErr    theError = noErr;
  1989.  
  1990.     gInBackground = false;
  1991.  
  1992.     InitGraf((Ptr) &qd.thePort);
  1993.     InitFonts();
  1994.     InitWindows();
  1995.     InitMenus();
  1996.     TEInit();
  1997.     InitDialogs(nil);
  1998.     InitCursor();
  1999.  
  2000.     for (count = 1; count <= 3; count++)
  2001.         EventAvail(everyEvent, &event);
  2002.     
  2003.     theError = Gestalt( gestaltQuickTimeVersion, &theResult );
  2004.     if( theError ) return theError;
  2005.     if( theResult < 0x03000000 ) return userCanceledErr;
  2006.     
  2007.     menuBar = GetNewMBar(kMenuBarID);            /* read menus into menu bar */
  2008.     if( !menuBar ) return memFullErr;
  2009.     SetMenuBar(menuBar);                    /* install menus */
  2010.     DisposeHandle(menuBar);
  2011.     AppendResMenu(GetMenuHandle(mApple), 'DRVR');    /* add DA names to Apple menu */
  2012.     AdjustMenus();
  2013.  
  2014.     InitAppleEvents();
  2015.     SetCursor(&qd.arrow);
  2016.     
  2017.     return noErr;
  2018. } /*Initialize*/
  2019.  
  2020.  
  2021. //
  2022. //    main
  2023. //
  2024. void main(void)
  2025. {
  2026.     MaxApplZone();                    /* expand the heap so code segments load at the top */
  2027.  
  2028.     if( noErr == Initialize() )        /* initialize the program */
  2029.     {
  2030.         EventLoop();                /* call the main event loop */
  2031.     }
  2032. }
  2033.